package aps.module_Machines;

//Java
import net.minecraft.src.Block;
import net.minecraft.src.Container;
import net.minecraft.src.EntityItem;
import net.minecraft.src.ICrafting;
import net.minecraft.src.ItemStack;
import net.minecraft.src.NBTTagCompound;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.liquids.ILiquidTank;
import net.minecraftforge.liquids.ITankContainer;
import net.minecraftforge.liquids.LiquidContainerRegistry;
import net.minecraftforge.liquids.LiquidStack;
import net.minecraftforge.liquids.LiquidTank;
import aps.module_Core.GuiIDs;
import aps.module_Core.TileEntityAPSPowered;
import aps.module_Core.module_Core.APSBlockTypes;
import buildcraft.BuildCraftCore;
import buildcraft.api.gates.Action;
import buildcraft.api.gates.IAction;
import buildcraft.api.gates.IActionReceptor;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.api.transport.IPipeConnection;
import buildcraft.core.IMachine;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.triggers.ActionMachineControl;
import buildcraft.core.utils.Utils;
//Vanilla Minecraft
//APS
//Buildcraft

public class TileEntityExtractor extends TileEntityAPSPowered implements IPowerReceptor, ITankContainer, IActionReceptor, IMachine, IPipeConnection
{
	static int LavaID = Block.lavaStill.blockID;
	static int LavaCapacity = LiquidContainerRegistry.BUCKET_VOLUME * 20;
	static int MinimumEnergy = 5;
	static int OptimumEnergy = 250;
	static int LiquidSideTex = 3;
	
	float PowerLevelMA;
	int PowerLevelMANodes = 100;
	float CurPowerLevel;
	float LastPowerLevel;
	String[] products; //client side only
	//int LavaLevel;
	
	LiquidTank tank = new LiquidTank(LavaCapacity);
	
	public TileEntityExtractor()
	{
		super( 0, 37, 1, 2, 0, 1, OptimumEnergy, 1, OptimumEnergy, APSBlockTypes.Machine);
		hasGUI = true;
		GuiID = GuiIDs.GUI_EXTRACTOR;
		PowerLevelMA = 0;
		//LavaLevel = 0;
	}
	
	int LavaCounter = 0;
	@Override
	public void updateEntity()
	{
		super.updateEntity();
		
		if(lastMode == ActionMachineControl.Mode.On || lastMode == ActionMachineControl.Mode.Loop || lastMode == ActionMachineControl.Mode.Unknown)
        {
			PowerLevelMA -= (PowerLevelMA / PowerLevelMANodes);
			PowerLevelMA += powerProvider.useEnergy(1, OptimumEnergy, true);
			CurPowerLevel = (PowerLevelMA / PowerLevelMANodes);
			LastPowerLevel = CurPowerLevel;
			
			while (tank.getLiquid() != null && tank.getLiquid().amount > 0 && CurPowerLevel > MinimumEnergy)
			{
				tank.drain(LiquidContainerRegistry.BUCKET_VOLUME / 160, true);
				CurPowerLevel -= MinimumEnergy;
				
				ItemStack itemstack = module_Machines.ExtractorProducts.getRandomProduct();
		        if(itemstack != null)
		        {
		        	//StackUtils has since been removed in the 3.2 API, updated to simply Utils - Seph
		        	
		        	ItemStack added = Utils.addToRandomInventory(itemstack, worldObj, xCoord, yCoord, zCoord, ForgeDirection.UNKNOWN);
		        	itemstack.stackSize -= added.stackSize;
		        	
		        	if (itemstack.stackSize > 0)
		        		Utils.addToRandomPipeEntry(this, ForgeDirection.UNKNOWN, itemstack);
		        	
		        	if (itemstack.stackSize > 0) //addToRandomPipeEntry must alter the item stack when successful
		        	{
		        		EntityItem entityitem = new EntityItem(worldObj, xCoord + 0.5, yCoord + 0.7, zCoord + 0.5, itemstack.copy());
						worldObj.spawnEntityInWorld(entityitem);
		        	}
		        		
		        	
		        }
			}
        }
		if(lastMode == ActionMachineControl.Mode.On) lastMode = ActionMachineControl.Mode.Off;
	}
	
	public String[] getPossibleProducts()
    {
		if (this.worldObj.isRemote)
		{
	    	if (module_Machines.ExtractorProducts == null) return new String[0];
	    	ItemStack[] P = module_Machines.ExtractorProducts.getAllProducts();
	    	String[] Output = new String[P.length];
	    	for(int i = 0; i < P.length; i++)
	    		Output[i] = P[i].stackSize + " " + P[i].getItem().getItemDisplayName(P[i]) + " " + (module_Machines.ExtractorProducts.chances[i] * 160) + "%";
	    	return Output;
		}
		//else
		return products; //list sent from server
    }
	
	public int powerRequest()
	{
		if (tank.getLiquid() != null && tank.getLiquid().amount > 0 && lastMode != ActionMachineControl.Mode.Off)
			return OptimumEnergy;
		else
			return 0;
	}

	//@Override
	public int empty(int quantityMax, boolean doEmpty)
	{
		return 0;
	}
	
	//@Override
	public void readFromNBT(NBTTagCompound nbttagcompound)
    {
    	super.readFromNBT(nbttagcompound);
		
    	PowerLevelMA = nbttagcompound.getFloat("powerlevelma");
    	fill(0, new LiquidStack(LavaID,nbttagcompound.getInteger("lavalevel")), true);
    }
	
	//@Override
    public void writeToNBT(NBTTagCompound nbttagcompound)
	{
    	super.writeToNBT(nbttagcompound);
    	
		nbttagcompound.setFloat("powerlevelma", PowerLevelMA);
    	nbttagcompound.setInteger("lavalevel", tank.getLiquid() == null ? 0 : tank.getLiquid().amount);
    }

	//@Override
	public int getLiquidId() {return LavaID;}
	
	//@Override
	//public int getLiquidQuantity() {return LavaLevel;}
	
	//@Override
	//public LiquidTank[] getLiquidSlots() {return new LiquidTank[] { new LiquidTank(LavaID, LavaLevel, LavaCapacity) };}
	
	public float getScaledLiquidQuantity(int MaxLevel) {return ((float)(tank.getLiquid() == null ? 0 : tank.getLiquid().amount) / (float) LavaCapacity) * MaxLevel;}
	
	public float getScaledPowerLevel(int MaxLevel) {return ((float) LastPowerLevel / OptimumEnergy) * MaxLevel;}
	
	public boolean getPowerSufficient() {return LastPowerLevel >= MinimumEnergy;}

	@Override
	public void kill() {}
	
	//@Override
	//public GuiScreen getGUI(EntityPlayer entityplayer) {
	//	return new GuiExtractor(this, entityplayer.inventory);
	//}

	public boolean isActive() { return tank.getLiquid() != null ? true : false; }

	//public boolean manageLiquids() {return true;}

	public boolean manageSolids() {return true;}

	//public boolean allowActions() {return true;}

	ActionMachineControl.Mode lastMode = ActionMachineControl.Mode.Unknown;
	//@Override
	public void actionActivated(Action action) {
		if (action == BuildCraftCore.actionOn) {
			lastMode = ActionMachineControl.Mode.On;
		} else if (action == BuildCraftCore.actionOff) {
			lastMode = ActionMachineControl.Mode.Off;
		} else if (action == BuildCraftCore.actionLoop) {
			lastMode = ActionMachineControl.Mode.Loop;
		}		
	}

	@Override
	public void actionActivated(IAction action) {
		return; //not used
	}

	@Override
	public int fill(ForgeDirection from, LiquidStack resource, boolean doFill) {
		return fill(0, resource, doFill);
	}

	@Override
	public int fill(int tankIndex, LiquidStack resource, boolean doFill) {
		if (resource.itemID == LavaID)
			return tank.fill(resource, doFill);
		return 0;
	}

	
	//Cannot pull lava out of the tank
	@Override
	public LiquidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
		return null;
	}

	@Override
	public LiquidStack drain(int tankIndex, int maxDrain, boolean doDrain) {
		return null;
	}

	@Override
	public ILiquidTank[] getTanks(ForgeDirection direction) {
		return new ILiquidTank[] {tank};
	}
	
	@Override
	public ILiquidTank getTank(ForgeDirection direction, LiquidStack liquidstack)
	{
		return this.tank;
	}
	
	public void sendGUIUpdates(Container container, ICrafting iCrafting)
	{
		iCrafting.sendProgressBarUpdate(container, 0, (this.tank.getLiquid() == null ? 0 : tank.getLiquid().amount));
		iCrafting.sendProgressBarUpdate(container, 1, (int)this.LastPowerLevel);
	}
	
	public void getGUIUpdates(int channel, int i)
	{
		if (channel == 0) this.tank = new LiquidTank(LavaID, i, LavaCapacity);
		if (channel == 1) this.LastPowerLevel = (float)i;
	}
	
	public PacketPayload getPacketPayload()
	{
		//Nothing to send
		if (module_Machines.ExtractorProducts == null) return super.getPacketPayload();
		ItemStack[] P = module_Machines.ExtractorProducts.getAllProducts();
		String Output; 
		PacketPayload payload = new PacketPayload(0, P.length, 0);
			for (int i = 0; i < P.length; i++)
			{
				Output = P[i].stackSize + " " + P[i].getItem().getItemDisplayName(P[i]) + " " + (module_Machines.ExtractorProducts.chances[i] * 160) + "%";
				payload.stringPayload[i] = Output;
			}
		return payload;
	}
	
	public void handleUpdatePacket(PacketUpdate packet)
	{
		String[] output = packet.payload.stringPayload;
	}

	@Override
	public boolean isPipeConnected(ForgeDirection with) {
		return true;
	}
}